package com.gmlive.recyclerview.gridpager.indicator

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener

/**

 * @Author svenj
 * @Date 2021/1/22
 * @Email svenjzm@gmail.com
 */
open class BasePageIndicator @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), IPageIndicator {
    protected var mRecyclerView: RecyclerView? = null
    protected var mCurrentPage: Int = 0

    private var mListener: OnPageChangeListener? = null
    private var mPageColumn = 1
    private var mScrollState = RecyclerView.SCROLL_STATE_IDLE

    private val mScrollListener = object : OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)

            onPageScrollStateChanged(newState)

            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                val layoutManager = recyclerView.layoutManager

                var position = 0
                if (layoutManager is GridLayoutManager) {
                    position = layoutManager.findFirstVisibleItemPosition()
                    val row = layoutManager.spanCount
                    position /= (row * mPageColumn)
                } else if (layoutManager is LinearLayoutManager) {
                    position = layoutManager.findFirstVisibleItemPosition()
                }

                onPageSelected(position)
            }
        }
    }

    override fun setRecyclerView(view: RecyclerView?) {
        if (mRecyclerView === view) {
            return
        }
        mRecyclerView?.removeOnScrollListener(mScrollListener)
        checkNotNull(view!!.adapter) { "RecyclerView does not have adapter instance." }
        mRecyclerView = view
        mRecyclerView?.addOnScrollListener(mScrollListener)
        invalidate()
    }

    override fun setRecyclerView(view: RecyclerView?, initialPosition: Int) {
        setRecyclerView(view)
        setCurrentItem(initialPosition)
    }

    override fun setCurrentItem(item: Int) {
        checkNotNull(mRecyclerView) { "RecyclerView has not been bound." }

        val currentPage = eachPageItemCount() * item

        mRecyclerView?.smoothScrollToPosition(currentPage)
        mCurrentPage = item
        invalidate()
    }

    override fun setOnPageChangeListener(listener: OnPageChangeListener?) {
        mListener = listener
    }

    override fun notifyDataSetChanged() {
        invalidate()
    }

    override fun setPageColumn(column: Int) {
        require(column > 0) { "[BasePageIndicator] column must be greater than zero" }
        this.mPageColumn = column
    }

    override fun onPageSelected(position: Int) {
        if (mCurrentPage == position) return

        mCurrentPage = position
        invalidate()

        mListener?.onPageSelected(position)
    }

    override fun onPageScrollStateChanged(state: Int) {
        mScrollState = state
        mListener?.onPageScrollStateChanged(state)
    }

    /**
     * The number of each page
     *
     * @return
     */
    protected open fun eachPageItemCount(): Int {
        if (mRecyclerView == null) {
            return 0
        }
        var row = 1
        val layoutManager = mRecyclerView!!.layoutManager
        if (layoutManager != null) {
            if (layoutManager is GridLayoutManager) {
                row = layoutManager.spanCount
            }
        }
        return row * mPageColumn
    }

    protected open fun pageCount(): Int {
        if (mRecyclerView?.adapter == null) return 0
        val itemCount = mRecyclerView!!.adapter!!.itemCount
        val eachPageCount = eachPageItemCount()
        if (eachPageCount <= 0) return 0
        return if (itemCount % eachPageCount == 0) itemCount / eachPageCount else itemCount / eachPageCount + 1
    }
}